package pl.edu.pk.mech.kkbus.service;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import org.springframework.stereotype.Service;

import pl.edu.pk.mech.kkbus.component.MyEntityManagerFactory;
import pl.edu.pk.mech.kkbus.entities.BusStop;
import pl.edu.pk.mech.kkbus.entities.DepartureTime;

@Service
public class BusStopService {
    
    EntityManagerFactory emf = MyEntityManagerFactory.get();
    
    public List<pl.edu.pk.mech.kkbus.dto.BusStop> getAllBusStops() {
        List<pl.edu.pk.mech.kkbus.dto.BusStop> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.BusStop>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT b FROM BusStop b ORDER BY b.sequence");
            List<BusStop> results = (List<BusStop>) query.getResultList();
            Iterator<BusStop> iterator = results.iterator();
            while (iterator.hasNext()) {                
                BusStop bs = iterator.next();
                
                List<pl.edu.pk.mech.kkbus.dto.DepartureTime> dt = new
                        LinkedList<pl.edu.pk.mech.kkbus.dto.DepartureTime>();
                
                for (DepartureTime t : bs.getDepartureTimes()) {
                    dt.add(new pl.edu.pk.mech.kkbus.dto.DepartureTime(t.getKey().getId(),
                            t.getTime(), t.getAttributes(), t.getSequence()));
                }
                
                result.add(new pl.edu.pk.mech.kkbus.dto.BusStop(bs.getKey().getId(),
                        bs.getName(), bs.getDirection(), bs.getPrice(), 
                        bs.getDistance(), bs.getSequence(), dt));
            }
            
            return result;         
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean create(pl.edu.pk.mech.kkbus.dto.BusStop bs) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            BusStop busStop = new BusStop(bs.getName(), bs.getDirection(),
                    bs.getPrice(), bs.getDistance(), bs.getSequence());
            em.persist(busStop);
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean update(long id, pl.edu.pk.mech.kkbus.dto.BusStop bs) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            BusStop busStop = em.find(BusStop.class, new Long(id));
            busStop.setDirection(bs.getDirection());
            busStop.setDistance(bs.getDistance());
            busStop.setName(bs.getName());
            busStop.setPrice(bs.getPrice());
            busStop.setSequence(bs.getSequence());
            em.persist(busStop);
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean delete(long id) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            BusStop busStop = em.find(BusStop.class, new Long(id));
            em.remove(busStop);
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean addDepartureTime(pl.edu.pk.mech.kkbus.dto.DepartureTime dt) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            BusStop bs = em.find(BusStop.class, new Long(dt.getBusStopId()));
            bs.getDepartureTimes().add(new DepartureTime(dt.getTime(),
                    dt.getAttributes(), dt.getSequence()));
            em.persist(bs);
            
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean deleteDepartureTime(long dtId, long bsId) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            BusStop bs = em.find(BusStop.class, new Long(bsId));
            Iterator<DepartureTime> dts = bs.getDepartureTimes().iterator();
            while (dts.hasNext()) {
                DepartureTime dt = dts.next();
                if (dt.getKey().getId() == dtId) {
                    // Usuwamy
                    dts.remove();
                    em.persist(bs);
                    return true;
                }
            }            
            
            return false;
        } catch(NoResultException e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }    
    }
}
